package com.innovation.action;

import com.google.protobuf.InvalidProtocolBufferException;
import com.googlecode.protobuf.format.JsonFormat;
import com.innovation.cache.PlayerCache;
import com.innovation.core.RequestSession;
import com.innovation.data.model.ModelData;
import com.innovation.data.model.Player;
import com.innovation.exception.PatException;
import com.innovation.message.AdminResultProto.AdminResult;
import com.innovation.message.PBMessageProto.PBMessage;
import com.innovation.service.DataPushService;
import com.innovation.service.PlayerService;
import com.innovation.util.NettyUtil;

/**
 * 管理接口操作基类
 * @author Administrator
 *
 */
public abstract class BaseAdminAction extends BaseAction{
	protected int data = ModelData.DATA_EMPTY;
	
	@Override
	public void run(RequestSession reqSession) throws Exception {
		//设置需要加载的数据
		setLoadedData();
		
		doInit(reqSession);
		Player player = reqSession.getPlayer();
		synchronized (player) {
			done(reqSession);
		}
		send2Client(reqSession);
	}
	
	protected abstract void done(String[] ps, Player player, AdminResult.Builder result);

	/**
	 * 从缓存中获取玩家数据,如果玩家不在缓存中则从DB中拉取,但是不将数据放入玩家缓存中
	 * @param openId
	 * @return
	 */
	protected Player getPlayer(String openId){
		Player temp = PlayerService.loadPlayerByOpenId(openId);
		Player player = PlayerCache.INSTANCE.getPlayerOnCache(temp.getId());
		//不在缓存中,则直接从DB加载
		if(player == null){
			player = temp;
		}
		PlayerService.loadPlayerDataFromDB(player, this.data);
		return player;
	}
	
	protected Player getPlayer(int playerId){
		Player player = PlayerCache.INSTANCE.getPlayerOnCache(playerId);
		//不在缓存中,则直接从DB加载
		if(player == null){
			player = PlayerService.loadPlayerById(playerId);
		}
		PlayerService.loadPlayerDataFromDB(player, this.data);
		return player;
	}
	
	/**
	 * 设置加载的数据(子类可覆盖该方法,按需求加载必须数据，默认不加载其他数据)
	 * @param data
	 */
	protected void setLoadedData(){
		this.data = ModelData.DATA_EMPTY;
	}
	
	@Override
	protected void doInit(RequestSession reqSession) throws PatException {
		Player player = getPlayer(reqSession.getPlayerId());
		if(player == null){
			throw new PatException("player not exists. playerId=" + reqSession.getPlayerId());
		}
		reqSession.setPlayer(player);
		//设置日志信息
		initLogData(reqSession);
	}
	
	@Override
	protected void send2Client(RequestSession reqSession) {
		try{
			//推送数据给在线玩家
			Player player = PlayerCache.INSTANCE.getOnlinePlayer(reqSession.getPlayerId());
			if(player != null){
				DataPushService.flush(player, null, 0);
			}
			
			PBMessage.Builder msg = reqSession.getResponse();
			try {
				String json = JsonFormat.printToString(AdminResult.parseFrom(msg.getData()));
				NettyUtil.sendHttpResponse("text/javascript", reqSession.getChannel(), json);
			} catch (InvalidProtocolBufferException e) {
			}
		}finally{
			//记录流水日志
			logFlow(reqSession);
		}
	}

	@Override
	protected void done(RequestSession reqSession) throws Exception {
		AdminResult.Builder result = AdminResult.newBuilder();
		
		PBMessage request = reqSession.getRequest();
		String[] ps = null;
		if(request.hasData()){
			ps = request.getData().toStringUtf8().split("[_]");
		}
		
		//具体操作
		try{
			done(ps, reqSession.getPlayer(), result);
		}catch (Exception e) {
			result.setResult(false);
			result.setDescription(e.getMessage());
		}
		
		//设置返回客户端数据
		reqSession.setResponseMsg(result.build());
	}
}
